package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
)

// Author: Wjy
// 自定义参数类型
type Name string
/*
// Set is called once, in command line order, for each flag present.
// The flag package may call the String method with a zero-valued receiver,
// such as a nil pointer.
type Value interface {
	String() string
	Set(string) error
}
*/
func (i *Name) String() string{
	return fmt.Sprint(*i)
}

func (i *Name) Set(value string) error {
	// 获取到输入参数的会自动调用set
	if len(*i) > 0{
		return errors.New("name flag already set")
	}
	*i = Name("eddycjy:" + value)
	return nil
}

func main() {
	var name Name
	flag.Var(&name, "name", "帮助信息")
	flag.Parse()
	log.Printf("name: %s", name)
}

func subOrder() {
	var name string
	// 子命令的使用
	flag.Parse()
	// 获取程序命令行输入得内容
	args := flag.Args()
	if len(args) <= 0 {
		return
	}
	/*
		// 如果解析失败，这些常量会导致 FlagSet.Parse 的行为与描述的一样。
		const (
			ContinueOnError ErrorHandling = iota // 返回一个描述性错误。
			ExitOnError                          // Call os.Exit(2) or for -h/-help Exit(0).
			PanicOnError                         // Call panic with a descriptive error.
		)
	*/
	switch args[0] {
	case "go":
		goCmd := flag.NewFlagSet("go", flag.ExitOnError)
		goCmd.StringVar(&name, "name", "Go语言", "帮助信息")
		// 需要第一个参数是go，才可以执行-name=新名字，如果不输入-name默认GO语言。-h显示帮助信息
		_ = goCmd.Parse(args[1:])
	case "php":
		phpCmd := flag.NewFlagSet("php", flag.ExitOnError)
		phpCmd.StringVar(&name, "name", "PHP语言", "帮助信息")
		// 需要第一个参数是php，才可以执行-name=新名字，如果不输入-name默认GO语言。-h显示帮助信息
		_ = phpCmd.Parse(args[1:])
	}
	log.Printf("name: %s", name)
}

func flagDemo() {
	// 标准库flag的使用
	var name string
	// 终端运行时输入-name=新名字，否则默认value.-h显示帮助信息
	flag.StringVar(&name, "name", "Go语言编程之旅", "帮助信息")
	// 终端运行时输入-n=新名字，否则默认value.-h显示帮助信息
	flag.StringVar(&name, "n", "go语言编程之旅", "帮助信息")
	flag.Parse()

	log.Printf("name: %s", name)
}
